package src.string;

import java.util.HashMap;
import java.util.HashSet;

public class no03 {  //无重复字符的最长子串，双指针，滑动窗口

    public static void main(String[] args) {
        String s = "abcabcbb";
        System.out.println(lengthOfLongestSubstring(s));
    }

    public static int lengthOfLongestSubstring(String s) {
        char[] arr = s.toCharArray();
        int left = 0;
        int maxLength = 0;
        HashSet<Character> set = new HashSet<>();
        set.add(s.charAt(0));
        for (int i = 1; i < arr.length; i++) {
            while (set.contains(arr[i])) {
                set.remove(arr[left]);
                left++;
                maxLength = Math.max(maxLength, i - left + 1);
            }
            set.add(arr[i]);

        }
        return maxLength;

    }

    public static int lengthOfLongestSubstring2(String s) {
        HashMap<Character, Integer> map = new HashMap<>();
        int maxLength = 0;
        int left = 0;
        // i 移动，作为右指针，因为 i 只需要一直右移即可，调整窗口只用左指针调
        for (int i = 0; i < s.length(); i++) {
            if (map.containsKey(s.charAt(i))) {

                //被判断的字符上一次出现的位置就在滑动窗口内，即 [ i，j ] 内， 则需要left改变位置
                //改变为该字符上次出现位置+1。也就是left = map.get(s.charAt(i)) + 1的情况。
                left = Math.max(left, map.get(s.charAt(i)) + 1);
            }
            map.put(s.charAt(i), i);

            maxLength = Math.max(maxLength, i - left + 1);
        }
        return maxLength;
    }

}
